#pragma once 
#include<iostream>
#include<vector>
#include<pthread.h>
#include"Log.hpp"
#include"sys/types.h"
#include"sys/socket.h"
#include"InetAddr.hpp"
#include"Thread.hpp"
#include<functional>
#include"ThreadPool.hpp"
#include"LockGuard.hpp"
using Task_t  = std::function<void()>;
class Message_Route{
    private:
        std::vector<InetAddr> _online_user;
        pthread_mutex_t _mutex;
    private:
        bool Is_exist(const InetAddr& user)
        {
            for(auto it : _online_user)
            {
                if(it == user)
                {
                    return true;
                }
            }
            return false;
        }
    public:
        Message_Route()
        {
            pthread_mutex_init(&_mutex,nullptr);
        }
        void AddUser(const InetAddr& user)
        {
            LockGuard lockguar(&_mutex);
            if(Is_exist(user))
            {
                return ;
            }
            _online_user.push_back(user);
        }
        void DelUser(const InetAddr& user)
        {
            LockGuard lockguard(&_mutex);
            auto iter = _online_user.begin();
            for(;iter != _online_user.end();iter++)
            {
                if(*iter == user)
                {
                    _online_user.erase(iter);
                    break;
                }
            }

        }
        void RouteHelper(int sockfd,const std::string& message,InetAddr& who)
        {   
            LockGuard lockguard(&_mutex);
            //消息转发
            for(auto m : _online_user)
            {
                std::string send_message = "\n[" + who.Ip() + ":" + std::to_string(who.Port()) + "]# " + message + "\n";
                struct sockaddr_in clientaddr = m.Addr();
                ::sendto(sockfd,message.c_str(),message.size(),0,(struct sockaddr *)&clientaddr,sizeof(clientaddr));
            }
        }
        void Route(int sockfd,std::string message,InetAddr& who)
        {
            //1. 我们任务，用户首次发消息，不光光是发消息，还要将自己，插入到在线用户中！
            AddUser(who);
            //2. 如果用户需要退出
            if(message =="Q" ||message == "quit")
            {
                DelUser(who);
            }
            Task_t t = std::bind(&Message_Route::RouteHelper,this,sockfd,message,who);
            ThreadPool<Task_t>::Get_instance()->Enqueue(t);
        }
        ~Message_Route()
        {
            pthread_mutex_destroy(&_mutex);
        }
};